package com.ruoyi.combat.service.externalServiceInvoker;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.combat.domain.CombatMethod;
import com.ruoyi.combat.domain.useralignment.CombatAlignmentTask;
import com.ruoyi.combat.domain.useralignment.CombatRelationWb;
import com.ruoyi.combat.domain.useralignment.CombatRelationZh;
import com.ruoyi.combat.mapper.CombatMethodMapper;
import com.ruoyi.combat.util.MethodUseUtils;
import com.ruoyi.combat.util.UserLocationUtil;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 课题五：网络用户身份保护调用算法
 */
@Component
public class NetworkUserIdentityProtectionService {

    private static final Logger log = LoggerFactory.getLogger(AntiPositioningService.class);
    @Autowired
    private UserLocationUtil userLocationUtil;
    @Autowired
    private CombatMethodMapper combatMethodMapper;
    @Autowired
    private MethodUseUtils methodUseUtils;
    @Value("${keti5.funcation0Path}")
    private String funcation0Path;


    /**
     * 对齐算法
     *
     * @Param algorithm 算法名称
     */
    public String aligning(String algorithm, List<CombatRelationWb> wbList, List<CombatRelationZh> zhList, String wbUserId, String zhUserId, Long id) throws IOException {
        // 获取当前服务器时间戳
        long timeStamp = System.currentTimeMillis();
        // 文件存储位置
        String path = funcation0Path + "dataspace\\";
        String weiboFilePath = userLocationUtil.writeWbFile(path, String.valueOf(timeStamp), wbList, wbUserId);
        weiboFilePath = "dataspace" + weiboFilePath.split("dataspace")[1];
        String zhFilePath = userLocationUtil.writezhFile(path, String.valueOf(timeStamp), zhList, zhUserId);
        zhFilePath = "dataspace" + zhFilePath.split("dataspace")[1];
        // 获取wbList的id集合
        List<String> wbIdList = new ArrayList<>();
        wbIdList.add(wbUserId);
        // 获取知乎List的id集合
        List<String> zhIdList = new ArrayList<>();
        zhIdList.add(zhUserId);
        String groundTruthFilePath = userLocationUtil.writeGroundTruthFile(path, String.valueOf(timeStamp), wbIdList, zhIdList, false);
        groundTruthFilePath = "dataspace" + groundTruthFilePath.split("dataspace")[1];

        // 调用对齐算法
        CombatMethod combatMethod = combatMethodMapper.selectCombatMethodById(28L);
        if (combatMethod == null) {
            log.error("未查询到对齐算法");
            throw new BaseException("未查询到对齐算法");
        }
        String methodUrl = combatMethod.getMethodUrl();
        if (StrUtil.isBlank(methodUrl)) {
            log.error("未查询到对齐算法的请求地址");
            throw new BaseException("未查询到对齐算法的请求地址");
        }
        Map<String, Object> postParamMap = new HashMap<>(16);
        postParamMap.put("algorithm", algorithm);// 对齐算法
        postParamMap.put("source_dataset", weiboFilePath);// 微博数据集
        postParamMap.put("target_dataset", zhFilePath);// 知乎数据集
        postParamMap.put("groundtruth", groundTruthFilePath);// 真实数据集
        postParamMap.put("taskId", String.valueOf(id));// 警告记录id
        String postParam = JSONUtil.toJsonStr(postParamMap);
        // 调用算法
        Map<String, Object> map = methodUseUtils.methodUseLogs(28L, postParam);
        return null;
    }

    /**
     * 抗对齐
     *
     * @param modified            1-策略1虚拟用户布设策略；2-策略2虚拟用户混淆策略
     * @param alignedNode         抗对齐的目标用户id
     * @param addNodeNum          使用策略1虚拟用户布设策略时，设置增加的虚拟用户数量
     * @param callbackUrl         回调地址
     * @param similarNum          使用策略2虚拟用户混淆策略时，设置虚拟联通关系数量
     * @param ratio               使用策略2虚拟用户混淆策略时，给相似用户增添联通关系的比例
     * @param fileSimilarNodePath 虚拟用户和真实用户之间的相似用户文件
     * @param weiboFilePath       微博用户关系
     * @param zhFilePath          知乎用户关系
     */
    public CombatAlignmentTask antiAlignment(String modified, String alignedNode,
                                Integer addNodeNum, String callbackUrl,
                                Integer similarNum, String ratio, String weiboFilePath,
                                String zhFilePath, String fileSimilarNodePath,
                                CombatAlignmentTask combatAlignmentTask,
                                String warnId) {
        if (StringUtils.isNotBlank(modified) && modified.equals("1")) {
            CombatMethod combatMethod = combatMethodMapper.selectCombatMethodById(29L);
//            combatAlignmentTask.setMethodId(combatMethod.getId());
//            combatAlignmentTask.setMethodName(combatMethod.getMethodName());
            if (combatMethod == null) {
                log.error("未查询到抗对齐算法");
                throw new BaseException("未查询到抗对齐算法");
            }
            String methodUrl = combatMethod.getMethodUrl();
            if (StrUtil.isBlank(methodUrl)) {
                log.error("未查询到抗对齐算法的请求地址");
                throw new BaseException("未查询到抗对齐算法的请求地址");
            }
            Map<String, Object> postParamMap = new HashMap<>(16);
            postParamMap.put("modified", modified);
            postParamMap.put("aligned_node", alignedNode);
            postParamMap.put("add_n", addNodeNum);
            postParamMap.put("callback_url", callbackUrl);
            postParamMap.put("file_similar_node", fileSimilarNodePath);
            postParamMap.put("file_weibo", weiboFilePath);
            postParamMap.put("file_zhihu", zhFilePath);
            postParamMap.put("warnId", warnId);
            String postParam = JSONUtil.toJsonStr(postParamMap);
            // 调用算法
            methodUseUtils.methodUseLogs(29L, postParam, "");
            System.out.println();
        } else if (StringUtils.isNotBlank(modified) && modified.equals("2")) {
            // 调用对齐算法
            CombatMethod combatMethod = combatMethodMapper.selectCombatMethodById(29L);
//            combatAlignmentTask.setMethodId(combatMethod.getId());
//            combatAlignmentTask.setMethodName(combatMethod.getMethodName());
            if (combatMethod == null) {
                log.error("未查询到预测IP-组织归属关系抗归属");
                throw new BaseException("未查询到预测IP-组织归属关系抗归属");
            }
            String methodUrl = combatMethod.getMethodUrl();
            if (StrUtil.isBlank(methodUrl)) {
                log.error("未查询到预测IP-组织归属关系抗归属算法的请求地址");
                throw new BaseException("未查询到预测IP-组织归属关系抗归属算法的请求地址");
            }
            Map<String, Object> postParamMap = new HashMap<>(16);
            postParamMap.put("modified", modified);
            postParamMap.put("aligned_node", alignedNode);
            postParamMap.put("similar_n", similarNum);
            postParamMap.put("ratio", ratio);
            postParamMap.put("file_similar_node", fileSimilarNodePath);
            postParamMap.put("file_weibo", weiboFilePath);
            postParamMap.put("file_zhihu", zhFilePath);
            postParamMap.put("warnId", warnId);
            postParamMap.put("callback_url", callbackUrl);
            String postParam = JSONUtil.toJsonStr(postParamMap);
            // 调用算法
             methodUseUtils.methodUseLogs(29L, postParam,"");
            System.out.println();
        }
        return combatAlignmentTask;
    }

    /**
     * 抗社区检测
     *
     * @param dataFile      数据文件名
     * @param methodName    模型名称
     * @param targetNode    目标节点
     * @param callBackUrl   回调地址
     */
    public Map<String, Object> antiOverlap(String dataFile, String methodName,
                              String targetNode, String callBackUrl, CombatAlignmentTask combatAlignmentTask) {
        CombatMethod combatMethod = combatMethodMapper.selectCombatMethodById(42l);
//        combatAlignmentTask.setMethodId(combatMethod.getId());
//        combatAlignmentTask.setMethodName(combatMethod.getMethodName());
        if (combatMethod == null) {
            log.error("未查询到抗社区检测算法");
            throw new BaseException("未查询到抗社区检测算法");
        }
        String methodUrl = combatMethod.getMethodUrl();
        if (StrUtil.isBlank(methodUrl)) {
            log.error("未查询到抗社区检测算法的请求地址");
            throw new BaseException("未查询到抗社区检测算法的请求地址");
        }
        Map<String, Object> postParamMap = new HashMap<>(16);
        postParamMap.put("json_file", "data");
        postParamMap.put("method_name", methodName);
        postParamMap.put("target_node", targetNode);
        postParamMap.put("call_back_url", callBackUrl);
        postParamMap.put("N", 20);
        postParamMap.put("max_iter", 20);
        postParamMap.put("overlap_threshold", 0.5);
        String postParam = JSONUtil.toJsonStr(postParamMap);
        // 调用算法
        Map<String, Object> map = methodUseUtils.methodUseLogs1(42L, postParam,"");
        return map;
    }

    /**
     * 抗非重叠社区检测
     */
    public String antiNonOverlap(String dataFile, String methodName,
                                 Integer targetNodeNum, String callBackUrl) {
        CombatMethod combatMethod = combatMethodMapper.selectCombatMethodById(31L);
        if (combatMethod == null) {
            log.error("未查询到抗非重叠社区检测算法");
            throw new BaseException("未查询到抗非重叠社区检测算法");
        }
        String methodUrl = combatMethod.getMethodUrl();
        if (StrUtil.isBlank(methodUrl)) {
            log.error("未查询到抗非重叠社区检测算法的请求地址");
            throw new BaseException("未查询到抗非重叠社区检测算法的请求地址");
        }
        Map<String, Object> postParamMap = new HashMap<>(16);
        postParamMap.put("data_file", dataFile);
        postParamMap.put("method_name", methodName);
        postParamMap.put("target_node", targetNodeNum);
        postParamMap.put("call_back_url", callBackUrl);
        String postParam = JSONUtil.toJsonStr(postParamMap);
        // 调用算法
        Map<String, Object> map = methodUseUtils.methodUseLogs(31L, postParam);
        return null;
    }

    /**
     * 检测算法
     *
     * @param postParamMap 属性
     */
    public String checkFunction(Map<String, Object> postParamMap) {
        CombatMethod combatMethod = combatMethodMapper.selectCombatMethodById(32L);
        if (combatMethod == null) {
            log.error("未查询到检测算法");
            throw new BaseException("未查询到检测算法");
        }
        String methodUrl = combatMethod.getMethodUrl();
        if (StrUtil.isBlank(methodUrl)) {
            log.error("未查询到检测算法的请求地址");
            throw new BaseException("未查询到检测算法的请求地址");
        }

        String postParam = JSONUtil.toJsonStr(postParamMap);
        // 调用算法
        Map<String, Object> map = methodUseUtils.methodUseLogs(32L, postParam);
        return String.valueOf(map.get("ratio"));
    }

}
